package com.baizhi.shane.shane.controller;

import com.baizhi.shane.common.base.Result;
import com.baizhi.shane.constant.ApiMapping;
import com.baizhi.shane.constant.TableNameMapping;
import com.baizhi.shane.shane.entity.*;
import com.baizhi.shane.shane.service.*;
import com.baizhi.shane.sys.entity.SysUser;
import com.baizhi.shane.sys.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(TableNameMapping.TEST_CONTROLLER)
@Api(tags = "调试用")
public class TestController {

    @Resource
    private ShaneQuestionService shaneQuestionService;
    @Resource
    private ShaneCollectQuestionService shaneCollectQuestionService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private ShaneLikesQuestionService shaneLikesQuestionService;
    @Resource
    private ShaneEssayService shaneEssayService;
    @Resource
    private ShaneLikesEssayService shaneLikesEssayService;
    @Resource
    private ShaneCollectEssayService shaneCollectEssayService;
    @Resource
    private ShaneAgainstEssayService shaneAgainstEssayService;
    @Resource
    private ShaneAnswerService shaneAnswerService;
    @Resource
    private ShaneLikesAnswerService shaneLikesAnswerService;
    @Resource
    private ShaneAgainstAnswerService shaneAgainstAnswerService;
    @Resource
    private ShaneCollectAnswerService shaneCollectAnswerService;

    /**
     * TEST初始化问题点赞关系表
     *
     * @Author 闻柏智
     * @Date 16:11 2023/11/20
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化问题点赞关系表", notes = "TEST初始化问题点赞关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_QUESTION_LIKE)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitQuestionLike() {

        /* 查询所有用户 */
        List<SysUser> sysUserList = sysUserService
                .lambdaQuery()
                .select(SysUser::getId)
                .list();

        /* 提取所有用户ID */
        List<Long> userIdList = sysUserList
                .stream()
                .map(SysUser::getId)
                .collect(Collectors.toList());

        /* 查询所有问题 */
        List<ShaneQuestion> shaneQuestionList = shaneQuestionService
                .lambdaQuery()
                .select(ShaneQuestion::getId)
                .list();

        /* 提取所有问题ID */
        List<Long> questionIdList = shaneQuestionList
                .stream()
                .map(ShaneQuestion::getId)
                .collect(Collectors.toList());

        Random random = new Random();

        // 创建点赞对象列表
        List<ShaneLikesQuestion> shaneLikesQuestionList = new ArrayList<>();

        for (Long questionId : questionIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneLikesQuestion shaneLikesQuestion = new ShaneLikesQuestion();
                shaneLikesQuestion.setUserId(userId);
                shaneLikesQuestion.setQuestionId(questionId);
                shaneLikesQuestionList.add(shaneLikesQuestion);
            }

        }

        shaneLikesQuestionService.saveBatch(shaneLikesQuestionList);


        return Result.OK();
    }

    /**
     * TEST初始化问题收藏关系表
     *
     * @Author 闻柏智
     * @Date 16:49 2023/11/25
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化问题收藏关系表", notes = "TEST初始化问题收藏关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_QUESTION_COLLECT)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitQuestionCollect() {
        /* 查询所有用户 */
        List<SysUser> sysUserList = sysUserService
                .lambdaQuery()
                .select(SysUser::getId)
                .list();

        /* 提取所有用户ID */
        List<Long> userIdList = sysUserList
                .stream()
                .map(SysUser::getId)
                .collect(Collectors.toList());

        /* 查询所有问题 */
        List<ShaneQuestion> shaneQuestionList = shaneQuestionService
                .lambdaQuery()
                .select(ShaneQuestion::getId)
                .list();

        /* 提取所有问题ID */
        List<Long> questionIdList = shaneQuestionList
                .stream()
                .map(ShaneQuestion::getId)
                .collect(Collectors.toList());

        Random random = new Random();

        List<ShaneCollectQuestion> shaneCollectQuestionList = new ArrayList<>();

        for (Long questionId : questionIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneCollectQuestion shaneCollectQuestion = new ShaneCollectQuestion();
                shaneCollectQuestion.setUserId(userId);
                shaneCollectQuestion.setQuestionId(questionId);
                shaneCollectQuestionList.add(shaneCollectQuestion);
            }
        }
        shaneCollectQuestionService.saveBatch(shaneCollectQuestionList);
        return null;
    }

    /**
     * TEST初始化文章点赞关系表
     *
     * @Author 闻柏智
     * @Date 18:54 2023/11/20
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化文章点赞关系表", notes = "TEST初始化文章点赞关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_ESSAY_LIKE)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitEssayLike() {
        // 获取全部用户ID列表
        List<Long> userIdList = this.getAllUserIdList();
        /* 获取所有文章列表 */
        List<ShaneEssay> shaneEssayList = shaneEssayService
                .lambdaQuery()
                .select(ShaneEssay::getId)
                .list();
        /* 提取文章ID列表 */
        List<Long> essayIdList = shaneEssayList
                .stream()
                .map(ShaneEssay::getId)
                .collect(Collectors.toList());

        // 创建点赞对象列表
        List<ShaneLikesEssay> shaneLikesEssayList = new ArrayList<>();

        Random random = new Random();
        for (Long essayId : essayIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneLikesEssay shaneLikesEssay = new ShaneLikesEssay();
                shaneLikesEssay.setUserId(userId);
                shaneLikesEssay.setEssayId(essayId);
                shaneLikesEssayList.add(shaneLikesEssay);
            }

        }
        shaneLikesEssayService.saveBatch(shaneLikesEssayList);

        return Result.OK();

    }

    /**
     * TEST初始化文章反对关系表
     *
     * @Author 闻柏智
     * @Date 19:09 2023/11/20
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化文章反对关系表", notes = "TEST初始化文章反对关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_ESSAY_AGAINST)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitEssayAgainst() {
        // 获取全部用户ID
        List<Long> userIdList = this.getAllUserIdList();
        /* 获取全部文章 */
        List<ShaneEssay> shaneEssayList = shaneEssayService
                .lambdaQuery()
                .select(ShaneEssay::getId)
                .list();
        /* 提取所有文章ID列表 */
        List<Long> essayIdList = shaneEssayList
                .stream()
                .map(ShaneEssay::getId)
                .collect(Collectors.toList());

        List<ShaneAgainstEssay> shaneAgainstEssayList = new ArrayList<>();
        Random random = new Random();
        for (Long essayId : essayIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneAgainstEssay shaneAgainstEssay = new ShaneAgainstEssay();
                shaneAgainstEssay.setUserId(userId);
                shaneAgainstEssay.setEssayId(essayId);
                shaneAgainstEssayList.add(shaneAgainstEssay);
            }
        }
        this.shaneAgainstEssayService.saveBatch(shaneAgainstEssayList);

        return Result.OK();

    }

    /**
     * TEST初始化文章收藏关系表
     *
     * @Author 闻柏智
     * @Date 16:45 2023/11/25
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化文章收藏关系表", notes = "TEST初始化文章收藏关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_ESSAY_COLLECT)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitEssayCollect() {
        // 获取全部用户ID
        List<Long> userIdList = this.getAllUserIdList();
        /* 获取全部文章 */
        List<ShaneEssay> shaneEssayList = shaneEssayService
                .lambdaQuery()
                .select(ShaneEssay::getId)
                .list();
        /* 提取所有文章ID列表 */
        List<Long> essayIdList = shaneEssayList
                .stream()
                .map(ShaneEssay::getId)
                .collect(Collectors.toList());

        List<ShaneCollectEssay> shaneCollectEssayList = new ArrayList<>();
        Random random = new Random();
        for (Long essayId : essayIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneCollectEssay shaneCollectEssay = new ShaneCollectEssay();
                shaneCollectEssay.setUserId(userId);
                shaneCollectEssay.setEssayId(essayId);
                shaneCollectEssayList.add(shaneCollectEssay);
            }
        }
        shaneCollectEssayService.saveBatch(shaneCollectEssayList);

        return null;
    }


    /**
     * TEST初始化回答点赞关系表
     *
     * @Author 闻柏智
     * @Date 19:19 2023/11/20
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化回答点赞关系表", notes = "TEST初始化回答点赞关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_ANSWER_LIKE)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitAnswerLike() {
        // 用户ID列表
        List<Long> userIdList = this.getAllUserIdList();
        /* 回答列表 */
        List<ShaneAnswer> shaneAnswerList = shaneAnswerService
                .lambdaQuery()
                .select(ShaneAnswer::getId)
                .list();
        /* 回答ID列表 */
        List<Long> answerIdList = shaneAnswerList
                .stream()
                .map(ShaneAnswer::getId)
                .collect(Collectors.toList());

        List<ShaneLikesAnswer> shaneLikesAnswerList = new ArrayList<>();

        Random random = new Random();
        for (Long answerId : answerIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneLikesAnswer shaneLikesAnswer = new ShaneLikesAnswer();
                shaneLikesAnswer.setUserId(userId);
                shaneLikesAnswer.setAnswerId(answerId);
                shaneLikesAnswerList.add(shaneLikesAnswer);
            }

        }
        shaneLikesAnswerService.saveBatch(shaneLikesAnswerList);

        return Result.OK();
    }

    /**
     * TEST初始化回答反对关系表
     *
     * @Author 闻柏智
     * @Date 16:40 2023/11/25
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化回答反对关系表", notes = "TEST初始化回答点赞关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_ANSWER_AGAINST)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitAnswerAgainst() {
        List<Long> userIdList = this.getAllUserIdList();

        /* 回答列表 */
        List<ShaneAnswer> shaneAnswerList = shaneAnswerService
                .lambdaQuery()
                .select(ShaneAnswer::getId)
                .list();

        /* 回答ID列表 */
        List<Long> answerIdList = shaneAnswerList
                .stream()
                .map(ShaneAnswer::getId)
                .collect(Collectors.toList());

        List<ShaneAgainstAnswer> shaneAgainstAnswerList = new ArrayList<>();

        Random random = new Random();
        for (Long answerId : answerIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneAgainstAnswer shaneAgainstAnswer = new ShaneAgainstAnswer();
                shaneAgainstAnswer.setUserId(userId);
                shaneAgainstAnswer.setAnswerId(answerId);
                shaneAgainstAnswerList.add(shaneAgainstAnswer);
            }
        }

        shaneAgainstAnswerService.saveBatch(shaneAgainstAnswerList);
        return null;
    }

    /**
     * TEST初始化回答收藏关系表
     *
     * @Author 闻柏智
     * @Date 16:40 2023/11/25
     * @Param
     * @return com.baizhi.shane.common.base.Result<?>
     **/
    @ApiOperation(value = "TEST初始化回答收藏关系表", notes = "TEST初始化回答收藏关系表")
    @PostMapping(value = ApiMapping.TEST_INIT_ANSWER_COLLECT)
    @Transactional(rollbackFor = RuntimeException.class)
    public Result<?> testInitAnswerCollect() {
        List<Long> userIdList = this.getAllUserIdList();

        /* 回答列表 */
        List<ShaneAnswer> shaneAnswerList = shaneAnswerService
                .lambdaQuery()
                .select(ShaneAnswer::getId)
                .list();

        /* 回答ID列表 */
        List<Long> answerIdList = shaneAnswerList
                .stream()
                .map(ShaneAnswer::getId)
                .collect(Collectors.toList());

        List<ShaneCollectAnswer> shaneCollectAnswerList = new ArrayList<>();

        Random random = new Random();
        for (Long answerId : answerIdList) {
            int randomNum = (int) (Math.sqrt(8) * random.nextGaussian() + 2);
            int likeCount = Math.abs(randomNum);
            List<Long> randomFromList = this.getRandomFromList(userIdList, likeCount);
            for (Long userId : randomFromList) {
                ShaneCollectAnswer shaneCollectAnswer = new ShaneCollectAnswer();
                shaneCollectAnswer.setUserId(userId);
                shaneCollectAnswer.setAnswerId(answerId);
                shaneCollectAnswerList.add(shaneCollectAnswer);
            }
        }
        shaneCollectAnswerService.saveBatch(shaneCollectAnswerList);


        return null;
    }



    /**
     * 从List随机取出n个数
     *
     * @return java.util.List<java.lang.Long>
     * @Author 闻柏智
     * @Date 15:17 2023/11/20
     * @Param list
     * @Param n:
     **/
    public List<Long> getRandomFromList(List<Long> list, int n) {
        // 复制List
        List<Long> newList = new ArrayList<>(list);
        // 首先将List打乱顺序
        Collections.shuffle(list);
        // 取出前 n 个数
        List<Long> result = newList.subList(0, n);

        return result;
    }

    /**
     * 获取全部的用户ID列表
     *
     * @Author 闻柏智
     * @Date 16:13 2023/11/20
     * @Param
     * @return java.util.List<java.lang.Long>
     **/
    private List<Long> getAllUserIdList() {
        /* 查询所有用户 */
        List<SysUser> sysUserList = sysUserService
                .lambdaQuery()
                .select(SysUser::getId)
                .list();

        /* 提取所有用户ID */
        List<Long> userIdList = sysUserList
                .stream()
                .map(SysUser::getId)
                .collect(Collectors.toList());
        return userIdList;
    }

}
